'''
Created on 07/04/2009

@author: Edward
'''
from im.ds import dsconstants, dsofactory
from im.ds.dso import DSO
from im.ds.dst import DST
from im.event import eventconstants
from im.event.event import Event
from im.event.eventhandler import BaseEventHandler
from im.event.eventmanager import EventManager
from im.handler import messagetypeconstants
from im.speara2a import helper
from xml.etree import ElementTree
import datetime
import httplib
import os
import re

class PublicApplicationStatusHTTPRequestHandler(BaseEventHandler):
    '''
    classdocs
    '''

    def __init__(self):
        '''
        Constructor
        '''
    # Given the numeric portion of the SPEAR reference number, calculate the check character.
    def calculate_spear_reference(self, num):
            total = 0
            mult = 7
            for n in num:
                    total += int(n) * mult
                    mult -= 1
            return 'AVTSPMJHECBA'[total % 11]
    
    # Validate the format (Snnnnnnx) and check character of a SPEAR reference number.
    def check_spear_reference(self, ref):
        match = re.match('^S(\d{6})([ABCEHJMPSTV]{1})$', ref)
        if match is not None:
                if self.calculate_spear_reference(match.group(1)) == match.group(2):
                        return True
        return False
    
    def do(self, data):
        dso = data
        http_request = dso.get_dst(subject=dsconstants.SUBJECT_ROOT,
                    predicate=dsconstants.PREDICATE_HTTP_REQUEST).get_literal()
        lock = dso.get_dst(subject=dsconstants.SUBJECT_ROOT,
                    predicate=dsconstants.PREDICATE_LOCK).get_literal()
        spear_reference_dst = dso.get_dst(subject=dsconstants.SUBJECT_FORM_DATA,
                    predicate=dsconstants.PREDICATE_SPEAR_REFERENCE_NUMBER) 

        if spear_reference_dst and self.check_spear_reference(spear_reference_dst.get_literal()):
            dst1 = DST(subject=dsconstants.SUBJECT_ROOT, 
                      predicate=dsconstants.PREDICATE_MESSAGE_TYPE, 
                      literal=messagetypeconstants.PUBLIC_APPLICATION_STATUS_TEST_REQUEST_MESSAGE_TYPE)
            dst2 = DST(subject=dsconstants.SUBJECT_ROOT, 
                      predicate=dsconstants.PREDICATE_MESSAGE_DESTINATION_NODE, 
                      literal="node_spear")
            dst3 = DST(subject=dsconstants.SUBJECT_ROOT, 
                      predicate=dsconstants.PREDICATE_MESSAGE_CONTENT, 
                      object=dsconstants.SUBJECT_MESSAGE_CONTENT)
            dst4 = DST(subject=dsconstants.SUBJECT_MESSAGE_CONTENT, 
                      predicate=dsconstants.PREDICATE_SPEAR_REFERENCE_NUMBER, 
                      literal=spear_reference_dst.get_literal())
            dst5 = DST(subject=dsconstants.SUBJECT_ROOT, 
                      predicate=dsconstants.PREDICATE_HTTP_REQUEST, 
                      literal=http_request)       
            dst6 = DST(subject=dsconstants.SUBJECT_ROOT, 
                      predicate=dsconstants.PREDICATE_LOCK, 
                      literal=lock)
            new_dso = DSO([dst1, dst2, dst3, dst4, dst5, dst6])
            event = Event(eventconstants.SEND_TO_HUB_EVENT_TYPE, new_dso)
            EventManager().add_event(event)
        else:
            relative_path = "../../../pages/im/imerror.html"
            
            fault_message = "invalid-spear-reference"
            # get the html template
            template_path = os.path.join(os.path.dirname(__file__), relative_path)
            file = open(template_path)
            html_template_string = file.read()
            html_string = html_template_string.replace('${fault_message}', fault_message)
            new_dso = dsofactory.create_dso_for_im_http_response_handler(httplib.OK, 
                                                                   'text/html', 
                                                                   html_string, 
                                                                   http_request, 
                                                                   lock)
            event = Event(eventconstants.HTTP_RESPONSE_EVENT_TYPE, new_dso)
            EventManager().add_event(event)
            print 'End Request: ' + str(datetime.datetime.now())

class PublicApplicationStatusWebServiceRequestHandler(BaseEventHandler):
    
    def do(self, data):
        dso = data

        spear_reference_number_dst = dso.get_dst(subject=dsconstants.SUBJECT_MESSAGE_CONTENT,
                                 predicate=dsconstants.PREDICATE_SPEAR_REFERENCE_NUMBER)
        spear_reference_number = spear_reference_number_dst.get_literal()
                
        # create web service name dst
        web_service_name_dst = DST(subject=dsconstants.SUBJECT_ROOT,
            predicate=dsconstants.PREDICATE_SPEAR_A2A_WEB_SERVICE_NAME,
            literal='LxSpearApplication_2_0')
        
        # create soap message
        access_token = helper.get_access_token()
        env = ElementTree.Element('{http://schemas.xmlsoap.org/soap/envelope/}Envelope')
        body = ElementTree.SubElement(env, '{http://schemas.xmlsoap.org/soap/envelope/}Body')
        getapp = ElementTree.SubElement(body, '{http://test.webservice.spear.lx.dse.vic.gov.au}getApplication')
        getapp.append(access_token)
        ref = ElementTree.SubElement(getapp,
            '{http://test.webservice.spear.lx.dse.vic.gov.au}spearRef')
        ref.text = spear_reference_number      
        soap = '<?xml version="1.0" encoding="utf-8" ?>\r\n' + ElementTree.tostring(env)        
        
        soap_message_dst = DST(subject=dsconstants.SUBJECT_ROOT,
            predicate=dsconstants.PREDICATE_SOAP_MESSAGE,
            literal=soap)        
        
        web_service_response_event_type_dst = DST(subject=dsconstants.SUBJECT_ROOT, 
            predicate=dsconstants.PREDICATE_WEB_SERVICE_RESPONSE_EVENT_TYPE,
            literal=eventconstants.PUBLIC_APPLICATION_STATUS_TEST_WEB_SERVICE_RESPONSE_EVENT_TYPE)
        
        # update dso
        dso.add_dst(soap_message_dst)
        dso.add_dst(web_service_name_dst)
        dso.add_dst(web_service_response_event_type_dst)
        event = Event(type=eventconstants.SEND_TO_SPEAR_EVENT_TYPE, data=dso)
        EventManager().add_event(event)